﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Runtime.Serialization;
using System.Windows.Forms;

namespace CartoGraphic.Model2
{
    public class LineObj:BaseDrawingObj
    {
        private Point startPoint;
		private Point endPoint;
        private LocationPoint sPoint, ePoint;

		private const string entryStart = "Start";
		private const string entryEnd = "End";

		private GraphicsPath areaPath = null;

		private Pen areaPen = null;
		private Region areaRegion = null;


		public LineObj()
		{
			startPoint.X = 0;
			startPoint.Y = 0;
			endPoint.X = 1;
			endPoint.Y = 1;
			ZOrder = 0;

			Initialize();
		}

		public LineObj(int x1, int y1, int x2, int y2)
		{
			startPoint.X = x1;
			startPoint.Y = y1;
			endPoint.X = x2;
			endPoint.Y = y2;
			ZOrder = 0;
			TipText = String.Format("Line Start @ {0}-{1}, End @ {2}-{3}", x1, y1, x2, y2);
			Initialize();
		}

        //public LineObj(int x1, int y1, int x2, int y2, DrawingPens.PenType p)
        //{
        //    startPoint.X = x1;
        //    startPoint.Y = y1;
        //    endPoint.X = x2;
        //    endPoint.Y = y2;
        //    DrawPen = DrawingPens.SetCurrentPen(p);
        //    PenType = p;
        //    ZOrder = 0;
        //    TipText = String.Format("Line Start @ {0}-{1}, End @ {2}-{3}", x1, y1, x2, y2);
        //    Initialize();
        //}

		public LineObj(int x1, int y1, int x2, int y2, Color lineColor, int lineWidth)
		{
			startPoint.X = x1;
			startPoint.Y = y1;
			endPoint.X = x2;
			endPoint.Y = y2;
			Color = lineColor;
			PenWidth = lineWidth;
			ZOrder = 0;
			TipText = String.Format("Line Start @ {0}-{1}, End @ {2}-{3}", x1, y1, x2, y2);

			Initialize();
		}


        public override void Draw(Graphics g,GraphicsProperties gps)
		{
			g.SmoothingMode = SmoothingMode.AntiAlias;
            Pen pen = new Pen(gps.BorderColor);
			GraphicsPath gp = new GraphicsPath();
			gp.AddLine(startPoint, endPoint);
			g.DrawPath(pen, gp);
			gp.Dispose();
			pen.Dispose();
		}

		/// <summary>
		/// Clone this instance
		/// </summary>
		public override BaseDrawingObj Clone()
		{
			LineObj LineObj = new LineObj();
			LineObj.startPoint = startPoint;
			LineObj.endPoint = endPoint;

			FillDrawObjectFields(LineObj);
			return LineObj;
		}

		public override int HandleCount
		{
			get { return 2; }
		}


		public override Point GetHandle(int handleNumber)
		{
			GraphicsPath gp = new GraphicsPath();
			Matrix m = new Matrix();
			gp.AddLine(startPoint, endPoint);
			RectangleF pathBounds = gp.GetBounds();
			//m.RotateAt(Rotation, new PointF(pathBounds.Left + (pathBounds.Width / 2), pathBounds.Top + (pathBounds.Height / 2)), MatrixOrder.Append);
			gp.Transform(m);
			Point start, end;
			start = Point.Truncate(gp.PathPoints[0]);
			end = Point.Truncate(gp.PathPoints[1]);
			gp.Dispose();
			m.Dispose();
			if (handleNumber == 1)
				return start;
			else
				return end;
		}

		public override int HitTest(Point point)
		{
			if (Selected)
				for (int i = 1; i <= HandleCount; i++)
				{
					GraphicsPath gp = new GraphicsPath();
					gp.AddRectangle(GetHandleRectangle(i));
					bool vis = gp.IsVisible(point);
					gp.Dispose();
					if (vis)
						return i;
				}
			if (PointInObject(point))
				return 0;
			return -1;
		}

		protected override bool PointInObject(Point point)
		{
			CreateObjects();
			return AreaRegion.IsVisible(point);
		}

		public override bool IntersectsWith(Rectangle rectangle)
		{
			CreateObjects();

			return AreaRegion.IsVisible(rectangle);
		}

		public override Cursor GetHandleCursor(int handleNumber)
		{
			switch (handleNumber)
			{
				case 1:
				case 2:
					return Cursors.SizeAll;
				default:
					return Cursors.Default;
			}
		}

		public override void MoveHandleTo(Point point, int handleNumber)
		{
			if (handleNumber == 1)
				startPoint = point;
			else
				endPoint = point;

			Dirty = true;
			Invalidate();
		}

		public override void Move(int deltaX, int deltaY)
		{
			startPoint.X += deltaX;
			startPoint.Y += deltaY;

			endPoint.X += deltaX;
			endPoint.Y += deltaY;
			Dirty = true;
			Invalidate();
		}

		public override void SaveToStream(SerializationInfo info, int orderNumber, int objectIndex)
		{
			
		}

		public override void LoadFromStream(SerializationInfo info, int orderNumber, int objectIndex)
		{
			
		}

		protected void Invalidate()
		{
			if (AreaPath != null)
			{
				AreaPath.Dispose();
				AreaPath = null;
			}

			if (AreaPen != null)
			{
				AreaPen.Dispose();
				AreaPen = null;
			}

			if (AreaRegion != null)
			{
				AreaRegion.Dispose();
				AreaRegion = null;
			}
		}

		protected virtual void CreateObjects()
		{
			if (AreaPath != null)
				return;
			AreaPath = new GraphicsPath();
			AreaPen = new Pen(Color.Black, PenWidth < 7 ? 7 : PenWidth);
			if (startPoint.Equals((Point)endPoint))
			{
				endPoint.X++;
				endPoint.Y++;
			}
			AreaPath.AddLine(startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
			AreaPath.Widen(AreaPen);

			AreaRegion = new Region(AreaPath);
		}

		protected GraphicsPath AreaPath
		{
			get { return areaPath; }
			set { areaPath = value; }
		}

		protected Pen AreaPen
		{
			get { return areaPen; }
			set { areaPen = value; }
		}

		protected Region AreaRegion
		{
			get { return areaRegion; }
			set { areaRegion = value; }
		}

        //protected LocationPoint SPoint
        //{
        //    get
        //    {
        //        return sPoint;
        //    }
        //    set { sPoint = value; }
        //}

        //protected LocationPoint EPoint
        //{
        //    get
        //    {
        //        return ePoint;
        //    }
        //    set { ePoint = value; }
        //}
	}

}
